package com.mgg.user.service.user.impl;

import com.mgg.common.client.message.MessageClient;
import com.mgg.common.dao.DaoSupport;
import com.mgg.common.enums.UserRoleEnum;
import com.mgg.common.exception.ServiceException;
import com.mgg.common.util.BeanUtils;
import com.mgg.common.util.UUIDUtils;
import com.mgg.user.entity.ProviderUserDO;
import com.mgg.user.entity.ShopDO;
import com.mgg.common.entity.UserDO;
import com.mgg.user.enums.UserResultEnum;
import com.mgg.user.service.BaseUserService;
import com.mgg.user.service.profile.ProfileService;
import com.mgg.user.service.user.UserService;
import com.mgg.user.vo.*;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;

@Service("userService")
public class UserServiceImpl implements UserService{

    @Autowired
    private BaseUserService baseUserService;

    @Autowired
    private ProfileService profileService;

    @Autowired
    private DaoSupport dao;

    @Autowired
    @Qualifier("poolTaskExecutor")
    private Executor executor;

    @Autowired
    private MessageClient messageClient;

    @Override
    public UserInfoVO getUserInfoByUserId(String userId) {
        UserDO userDO = baseUserService.getUserByUserId(userId);
        if (userDO == null) {
            throw new ServiceException(UserResultEnum.USER_NOT_FIND.getCode(),UserResultEnum.USER_NOT_FIND.getMessage());
        }
        UserInfoVO userInfoVO = new UserInfoVO();
        BeanUtils.copyProperties(userDO,userInfoVO);
        userInfoVO.setShop(initShopInfo(userId));
        userInfoVO.setProviderUser(initProviderUserInfo(userId));
        IdentifyCardVO identifyCardVO = profileService.getUserIdentityCard(userId);
        if (identifyCardVO != null) {
            userInfoVO.setIdentifyStatus(identifyCardVO.getStatus());
        } else {
            userInfoVO.setIdentifyStatus(99);
        }
        return userInfoVO;
    }

    @Override
    public UserInfoVO getUserInfoByShopCode(String shopCode) {
        UserDO userDO = baseUserService.getUserByShopCode(shopCode);
        if (userDO == null) {
            throw new ServiceException(UserResultEnum.USER_NOT_FIND.getCode(),UserResultEnum.USER_NOT_FIND.getMessage());
        }
        String userId = userDO.getUserId();

        UserInfoVO userInfoVO = new UserInfoVO();
        BeanUtils.copyProperties(userDO,userInfoVO);
        userInfoVO.setShop(initShopInfo(userId));
        userInfoVO.setProviderUser(initProviderUserInfo(userId));
        IdentifyCardVO identifyCardVO = profileService.getUserIdentityCard(userId);
        if (identifyCardVO != null) {
            userInfoVO.setIdentifyStatus(identifyCardVO.getStatus());
        } else {
            userInfoVO.setIdentifyStatus(99);
        }
        return userInfoVO;
    }

    private ShopVO initShopInfo(String userId) {
        ShopDO shopDO = baseUserService.getShopByUserId(userId);
        ShopVO shopVO = new ShopVO();
        if(shopDO != null) {
            shopVO.setShopCode(shopDO.getShopCode());
            shopVO.setShopName(shopDO.getShopName());
        }
        return shopVO;
    }

    private ProviderUserVO initProviderUserInfo(String userId) {
        ProviderUserDO providerUserDO = baseUserService.getProviderUserByUserId(userId);
        ProviderUserVO providerUserVO = new ProviderUserVO();
        if(providerUserDO != null) {
            providerUserVO.setOpenid(providerUserDO.getProviderUserId());
            providerUserVO.setProviderId(providerUserDO.getProviderId());
            providerUserVO.setDisplayName(providerUserDO.getDisplayName());
            providerUserVO.setImageUrl(providerUserDO.getImageUrl());
        }
        return providerUserVO;
    }

    @Override
    public UserVO getUserByOpenid(String openid, String providerId) {
        Map<String,String> map = new HashMap<>();
        map.put("openid", openid);
        map.put("providerId", providerId);
        UserVO user = dao.findForObject("UserMapper.getUserByOpenid", map);
        return user;
    }

    @Override
    public UserVO getUserByShopCode(String shopCode) {
        UserVO user = dao.findForObject("UserMapper.getUserByShopCode", shopCode);
        return user;
    }

    @Override
    public UserVO getUserByPhone(String phone) {
        UserVO user = dao.findForObject("UserMapper.getUserByPhone", phone);
        return user;
    }

    @Override
    public void saveVipUser(String phone, String inviteCode, String realName, String superId) {
        String userId = UUIDUtils.get32UUID();
        // 插入用户信息表
        Map<String, Object> map = new HashMap<>();
        map.put("phone", phone);
        map.put("inviteCode", inviteCode);
        map.put("realName", realName);
        map.put("realName", "会员" + phone.substring(7));
        map.put("userId", userId);
        map.put("userStatus", "1");
        String shopCode = dao.findForObject("UserMapper.getSequenceNum", "shop_code");
        map.put("shopCode", shopCode);
        dao.save("UserMapper.insertUser", map);

        // 插入用户权限表
        map.put("roleCode", UserRoleEnum.VIP.getCode());
        map.put("roleName", UserRoleEnum.VIP.getName());
        dao.save("UserMapper.insertUserRole", map);

        // 插入用户账户表
        map.put("total_income", 0);
        map.put("amount", 0);
        map.put("pre_amount", 0);
        dao.save("UserMapper.insertUserAccount", map);

        // 插入用户上级关系表
        map.put("superId", superId);
        dao.save("UserMapper.insertUserSuper", map);
    }

    @Override
    public BigDecimal getUserMCoin(String userId) {
        return dao.findForObject("UserMapper.getUserMCoin", userId);
    }

    @Override
    public Integer getUserCoupon(String userId) {
        return dao.findForObject("UserMapper.getUserCoupon", userId);
    }

    @Override
    public void vipToShopKeeper(String userId, String shopCode, String registTime, String remark) {
        // 修改上级
        UserDO inviteUser = baseUserService.getUserByShopCode(shopCode);
        Map<String, Object> map = new HashMap<>();
        UserDO superUser = baseUserService.getSuperUserByUserId(inviteUser.getUserId());
        if (UserRoleEnum.TUTOR.getCode().equals(inviteUser.getRoleCode())) {
            map.put("superId", superUser.getUserId());
        } else {
            map.put("superId", inviteUser.getUserId());
        }
        map.put("userId", userId);
        dao.update("UserMapper.updateUserSuper", map);

        //角色为店主
        map.put("roleCode", UserRoleEnum.TUTOR.getCode());
        map.put("roleName", UserRoleEnum.TUTOR.getName());
        dao.update("UserMapper.updateUserRole", map);
        map.put("remark", remark);
        dao.update("UserMapper.insertUserUpgradeLog", map);

        //插入用户上级code表
        String superId = inviteUser.getUserId();
        String superCodes = dao.findForObject("UserMapper.getUserCodesByUserId", superId);
        if (StringUtils.isEmpty(superCodes)) {
            map.put("codes", shopCode);
        } else {
            map.put("codes", superCodes + "-" + shopCode);
        }

        //查看是否已经开过店
        ShopDO shop = baseUserService.getShopByUserId(userId);
        if (shop == null) {
            //新建店
            map.put("shopName", "");
            map.put("createtime", registTime);
            map.put("shopCode", dao.findForObject("UserMapper.getShopCodeByUserId", userId));
            dao.save("UserMapper.insertShop", map);
            dao.save("UserMapper.insertShopSalesCount", map);
            dao.save("UserMapper.insertSuperUserCodes", map);
        } else {
            map.put("shopCode", shop.getShopCode());
            dao.update("UserMapper.updateShopStatus", map);
            dao.update("UserMapper.updateSuperUserCodes", map);
        }

        //发送短信
        CompletableFuture
                .runAsync(() -> {
                    try {
                        UserDO user = baseUserService.getUserByUserId(userId);
                        String name = user.getRealName();
                        String phone = user.getPhone().substring(7);
                        String mobile = inviteUser.getPhone();
                        messageClient.sendRegistShopkeeperNotice(userId, name);
                        messageClient.sendNewShopkeeperNotice(inviteUser.getUserId(), mobile, name, phone);
                        if (superUser != null) {
                            String shopkeeper = inviteUser.getRealName();
                            mobile = superUser.getPhone();
                            messageClient.sendTeamShopkeeperNotice(superUser.getUserId(), mobile, shopkeeper, name, phone);
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }, executor);
    }

    @Override
    public UserInfoVO getAppUserById(String userId) {
        String ruId = dao.findForObject("UserMapper.getRegistUserId", userId);
        if (StringUtils.isEmpty(ruId)) {
            return null;
        }
        return getUserInfoByUserId(ruId);
    }
}
